package edu.sdjzu.exam.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import edu.sdjzu.exam.common.CommonResponse;
import edu.sdjzu.exam.mapper.ActivityLogMapper;
import edu.sdjzu.exam.domain.ActivityLog;
import edu.sdjzu.exam.domain.auth.Role;
import edu.sdjzu.exam.domain.auth.User;
import edu.sdjzu.exam.enums.AuthResultCode;
import edu.sdjzu.exam.service.auth.AuthService;
import edu.sdjzu.exam.service.rbac.RbacService;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AuthServiceImpl implements AuthService {

    private static final long INVALID_USER_ID = 0L; // 假设 0 是无效ID（根据业务调整）

    @Autowired
    private RbacService rbacService;
    private static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private ActivityLogMapper activityLogMapper;

    @Override
    public CommonResponse<Object> login(String username, String password) {
//        log.info("开始登录 - 用户名: {}", username);
        try {
            User user = rbacService.findUserByUsername(username);
            if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
                logActivity(INVALID_USER_ID, "login", null, "登录失败: 用户不存在 - " + username);
                return CommonResponse.fail(AuthResultCode.USER_NOT_FOUND.code, AuthResultCode.USER_NOT_FOUND.message);
            }

            StpUtil.login(user.getUserId());
            StpUtil.getSession().set("user", user);

            // 获取用户角色
            List<Role> roles = rbacService.findRolesByUserId(user.getUserId());

            // 构建登录响应数据
            Map<String, Object> loginData = new HashMap<>();
            loginData.put("token", StpUtil.getTokenValue());
            loginData.put("userInfo", Map.of(
                "userId", user.getUserId(),
                "username", user.getUsername(),
                "email", user.getEmail(),
                "roles", roles.stream().map(Role::getRoleName).collect(Collectors.toList()),
                    "realName",user.getRealname()
            ));

            logActivity(user.getUserId(), "login", null, "登录成功");
            return new CommonResponse<>(200, "成功", loginData);

        } catch (Exception e) {
            log.error("登录异常 - 用户名: {}, 错误: {}", username, e.getMessage());
            logActivity(INVALID_USER_ID, "login", null, "登录异常: " + e.getMessage());
            return CommonResponse.fail(AuthResultCode.ERROR.code, "系统错误，请联系管理员");
        }
    }

    @Override
    @Transactional
    public CommonResponse<String> register(String username, String password, String email, String name) {
        try {
            // 1. 检查用户是否存在
            User existingUser = rbacService.findUserByUsername(username);
            if (existingUser != null) {
                return CommonResponse.fail(AuthResultCode.USER_EXISTS.code, AuthResultCode.USER_EXISTS.message);
            }

            // 2. 创建用户
            User user = new User();
            user.setUsername(username);
            String encodedPassword = passwordEncoder.encode(password);
            user.setPassword(encodedPassword);
            user.setEmail(email);
            user.setRealname(name);

            rbacService.createUser(user);

            // 3. 验证用户创建
            User createdUser = rbacService.findUserByUsername(username);
            if (createdUser == null || createdUser.getUserId() == null) {
                throw new RuntimeException("用户创建失败");
            }

            // 4. 分配学生角色（默认）
            Role studentRole = rbacService.findRoleByName("student");
            if (studentRole == null) {
                throw new RuntimeException("学生角色不存在");
            }

            rbacService.assignRoleToUser(createdUser.getUserId(), studentRole.getRoleId());

            // 5. 记录日志
            logActivity(createdUser.getUserId(), "register", null, "学生注册成功: " + username);

            return CommonResponse.success("注册成功", null);

        } catch (Exception e) {
            log.error("注册失败 - 用户名: {}, 错误信息: {}", username, e.getMessage(), e);
            return CommonResponse.fail(AuthResultCode.ERROR.code, "注册失败: " + e.getMessage());
        }
    }

    @Override
    public CommonResponse<String> logout() {
        try {
            if (!StpUtil.isLogin()) {
                return CommonResponse.fail(AuthResultCode.NOT_LOGGED_IN.code, AuthResultCode.NOT_LOGGED_IN.message);
            }

            StpUtil.logout();
            return CommonResponse.success("注销成功", null);

        } catch (Exception e) {
            return CommonResponse.fail(AuthResultCode.ERROR.code, "注销失败: " + e.getMessage());
        }
    }


    @Override
    public CommonResponse<Object> getUserInfo() {
        try {
            if (!StpUtil.isLogin()) {
                return CommonResponse.fail(AuthResultCode.NOT_LOGGED_IN.code, AuthResultCode.NOT_LOGGED_IN.message);
            }

            Long userId = StpUtil.getLoginIdAsLong();
            User user = rbacService.findUserById(userId);
            if (user == null) {
                return CommonResponse.fail(AuthResultCode.USER_NOT_FOUND.code, AuthResultCode.USER_NOT_FOUND.message);
            }

            // 获取用户角色
            List<Role> roles = rbacService.findRolesByUserId(userId);
            
            // 构建返回数据
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userId", user.getUserId());
            userInfo.put("username", user.getUsername());
            userInfo.put("email", user.getEmail());
            userInfo.put("realname", user.getRealname());
            userInfo.put("roles", roles.stream().map(Role::getRoleName).collect(Collectors.toList()));
            userInfo.put("createdAt", user.getCreatedAt());

            return CommonResponse.success("获取用户信息成功", userInfo);

        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage(), e);
            return CommonResponse.fail(AuthResultCode.ERROR.code, "获取用户信息失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public CommonResponse<String> updateUser(String email, String realname, String password) {
        try {
            if (!StpUtil.isLogin()) {
                return CommonResponse.fail(AuthResultCode.NOT_LOGGED_IN.code, AuthResultCode.NOT_LOGGED_IN.message);
            }
            
            Long userId = StpUtil.getLoginIdAsLong();
            User user = rbacService.findUserById(userId);
            if (user == null) {
                return CommonResponse.fail(AuthResultCode.USER_NOT_FOUND.code, AuthResultCode.USER_NOT_FOUND.message);
            }
            
            // 更新用户信息
            boolean hasChanges = false;
            
            if (email != null && !email.trim().isEmpty() && !email.equals(user.getEmail())) {
                // 检查邮箱是否已被其他用户使用
                User existingUser = rbacService.findUserByEmail(email);
                if (existingUser != null && !existingUser.getUserId().equals(userId)) {
                    return CommonResponse.fail(AuthResultCode.USER_EXISTS.code, "该邮箱已被其他用户使用");
                }
                user.setEmail(email);
                hasChanges = true;
            }
            
            if (realname != null && !realname.equals(user.getRealname())) {
                user.setRealname(realname);
                hasChanges = true;
            }
            
            if (password != null && !password.trim().isEmpty()) {
                String encodedPassword = passwordEncoder.encode(password);
                user.setPassword(encodedPassword);
                hasChanges = true;
            }
            
            if (hasChanges) {
                rbacService.updateUser(user);
                logActivity(userId, "update_profile", null, "用户更新个人信息");
                return CommonResponse.success("用户信息更新成功", null);
            } else {
                return CommonResponse.success("没有信息需要更新", null);
            }
            
        } catch (Exception e) {
            log.error("更新用户信息失败: {}", e.getMessage(), e);
            return CommonResponse.fail(AuthResultCode.ERROR.code, "更新失败: " + e.getMessage());
        }
    }

    private void logActivity(Long userId, String action, Long examId, String details) {
        ActivityLog log = new ActivityLog();
        log.setUserId(userId);
        log.setAction(action);
        log.setExamId(examId);
        log.setCreatedAt(LocalDateTime.now());
        log.setDetails(details);
        activityLogMapper.insert(log);
    }
}
